﻿// --------------------------------------------------------------------------------------------------------------------- 
// <copyright file="CalculateCapacityTest.cs" company="Scrum for Team System">
//   None
// </copyright>
// <summary>
//   Defines the CalculateCapacityTest type.
// </summary>
// ---------------------------------------------------------------------------------------------------------------------
namespace ScrumForTeamSystem.Metrics.Test
{
    using System;

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Defines the CalculateCapacityTest type.
    /// </summary>
    [TestClass]
    public class CalculateCapacityTest
    {
        /// <summary>
        /// Test to prove that: Forecasting capacity should return a null value if insufficent sprint detail is provided.
        /// </summary>
        [TestMethod]
        public void Forecasting_capacity_should_return_a_null_value_if_insufficent_sprint_detail_is_provided()
        {
            var forecasting = new Forecasting();

            var capacity = 100d;
            var workRemaining = 100d;
            var sprintStart = new DateTime(2009, 1, 1);
            var sprintEnd = new DateTime(2009, 2, 1);

            var result = forecasting.GetNextCapacityTrendValue(workRemaining, false, null, null, null);

            Assert.IsNull(result);

            result = forecasting.GetNextCapacityTrendValue(workRemaining, false, null, null, sprintEnd);

            Assert.IsNull(result);

            result = forecasting.GetNextCapacityTrendValue(workRemaining, false, null, sprintStart, sprintEnd);

            Assert.IsNull(result);

            result = forecasting.GetNextCapacityTrendValue(workRemaining, false, capacity, sprintStart, sprintEnd);

            Assert.IsNotNull(result);
        }

        /// <summary>
        /// Test to prove that: Forecasting capacity should return a null value if there is never any work remaining.
        /// </summary>
        [TestMethod]
        public void Forecasting_capacity_should_return_a_null_value_if_there_is_never_any_work_remaining()
        {
            var forecasting = new Forecasting();

            var capacity = 100d;
            var workRemaining = default(double?);
            var sprintStart = new DateTime(2009, 1, 1);
            var sprintEnd = new DateTime(2009, 2, 1);

            var result = forecasting.GetNextCapacityTrendValue(workRemaining, false, capacity, sprintStart, sprintEnd);

            Assert.IsNull(result);
        }

        /// <summary>
        /// Test to prove that: Forecasting capacity with weekends excluded should return a sequence as indicated.
        /// </summary>
        [TestMethod]
        public void Forecasting_capacity_with_weekends_excluded_should_return_a_sequence_as_indicated()
        {
            var forecasting = new Forecasting();

            var workRemaing = 
                new[]
                {
                      100d, 
                      default(double?), 
                      default(double?), 
                      default(double?), 
                      default(double?),
                      default(double?), 
                      default(double?), 
                      default(double?), 
                      default(double?),
                      default(double?), 
                      default(double?)
                };

            var expected = new[] { 100d, 90d, 80d, 70d, 60d, 50d, 40d, 30d, 20d, 10d };
            var actual = new double?[expected.Length];

            var capacity = 100d;
            var sprintStart = new DateTime(2009, 1, 5); // Monday
            var sprintEnd = new DateTime(2009, 1, 16); // Friday

            for (var i = 0; i < expected.Length; i++)
            {
                actual[i] = forecasting.GetNextCapacityTrendValue(
                        workRemaing[i],
                        false,
                        capacity,
                        sprintStart,
                        sprintEnd);

                Assert.AreEqual(expected[i], actual[i]);
            }
        }

        /// <summary>
        /// Test to prove that: Forecasting capacity with weekends included should return a sequence as indicated.
        /// </summary>
        [TestMethod]
        public void Forecasting_capacity_with_weekends_included_should_return_a_sequence_as_indicated()
        {
            var forecasting = new Forecasting();

            var workRemaing =
                new[]
                {
                      120d, 
                      default(double?), 
                      default(double?), 
                      default(double?), 
                      default(double?),
                      default(double?), 
                      default(double?), 
                      default(double?), 
                      default(double?),
                      default(double?), 
                      default(double?),
                      default(double?), 
                      default(double?)
                };

            var expected = new[] { 120d, 110d, 100, 90d, 80d, 70d, 60d, 50d, 40d, 30d, 20d, 10d };
            var actual = new double?[expected.Length];

            var capacity = 120d; // 12 days (including weekends) gives us a daily capacity of 10
            var sprintStart = new DateTime(2009, 1, 5); // Monday
            var sprintEnd = new DateTime(2009, 1, 16); // Friday

            for (var i = 0; i < expected.Length; i++)
            {
                actual[i] = forecasting.GetNextCapacityTrendValue(
                        workRemaing[i],
                        true,
                        capacity,
                        sprintStart,
                        sprintEnd);

                Assert.AreEqual(expected[i], actual[i]);
            }
        }
    }
}
